// 策略模式定义了一系列算法，并将每个算法封装起来，是他们可以相互替换。
// 主要角色如下：
//  1，抽象策略，定义了公共接口
//  2，具体策略，实现抽象策略的接口
//  3，环境，持有一个策略类的引用，最终给客户端调用

#include <iostream>
#include <memory>

using namespace std;


class Strategy
{
    public:
    virtual void strategyMethod() = 0;
    virtual ~Strategy(){};

};


class StrategyA: public Strategy
{
    public:
    void strategyMethod(){
        std::cout<<"Using alg A."<< std::endl;
    }

};

class StrategyB: public Strategy
{
    public:
    void strategyMethod(){
        std::cout<<"Using alg B."<<std::endl;
    }
};


class Context
{
    private:
    Strategy* m_strategy;

    public:
    void setStrategy(Strategy* strategy){
        m_strategy = strategy;
    }

    Strategy* getStrategy(){
        return m_strategy;
    }

    void strategyMethod(){
        m_strategy->strategyMethod();
    }

};

int main(int argc, char const *argv[])
{
    unique_ptr<Context> context(new Context());

    // 实际应用过程中，修改这行代码就可以切换策略
    Strategy* strategy = new StrategyA();

    context->setStrategy(strategy);
    context->strategyMethod();
    delete strategy;

    std::cout<<"\n\nChange alg."<<std::endl;

    strategy = new StrategyB();
    context->strategyMethod();
    
    delete strategy;

    return 0;
}
